package trang;

import com.thaiopensource.relaxng.translate.Driver

import javax.xml.transform.Transformer
import javax.xml.transform.TransformerFactory
import javax.xml.transform.stream.StreamSource
import javax.xml.transform.stream.StreamResult

import org.gradle.api.*;
import org.gradle.api.tasks.*
import org.gradle.api.file.FileCollection

/**
 * Used for converting .rnc files to .xsd files.
 * @author Rob Winch
 */
class TrangPlugin implements Plugin<Project> {
    public void apply(Project project) {
        Task rncToXsd = project.tasks.create('rncToXsd', RncToXsd.class)
        rncToXsd.description = 'Converts .rnc to .xsd'
        rncToXsd.group = 'Build'
    }
}

/**
 * Converts .rnc files to .xsd files using trang and then applies an xsl file to cleanup the results.
 */
public class RncToXsd extends DefaultTask {
    @InputDirectory
    File rncDir

    @InputFile
    File xslFile

    @OutputDirectory
    File xsdDir

    @TaskAction
    public final void transform() {
        String xslPath = xslFile.absolutePath
        rncDir.listFiles( { dir, file -> file.endsWith('.rnc')} as FilenameFilter).each { rncFile ->
            File xsdFile = new File(xsdDir, rncFile.name.replace('.rnc', '.xsd'))
            String xsdOutputPath = xsdFile.absolutePath
            new Driver().run([rncFile.absolutePath, xsdOutputPath] as String[]);

            TransformerFactory tFactory = new net.sf.saxon.TransformerFactoryImpl()
            Transformer transformer =
                    tFactory.newTransformer(new StreamSource(xslPath))
            File temp = File.createTempFile("gradle-trang-" + xsdFile.name, ".xsd")
            xsdFile.withInputStream { is ->
                temp << is
            }
            StreamSource xmlSource = new StreamSource(temp)
            transformer.transform(xmlSource, new StreamResult(xsdFile))
            temp.delete()
        }
    }
}